package top.mydb.hejianwei.dm.pageCache;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

import top.mydb.hejianwei.common.Error;
import top.mydb.hejianwei.dm.page.Page;
import top.mydb.hejianwei.utils.Panic;

public interface PageCache {
    public static final int PAGE_SIZE = 1 << 13;
    public static final String DB_SUFFIX = ".db";
    int newPage(byte[] initData);
    Page getPage(int pageNo) throws Exception;
    void close();
    void release(Page page);

    void truncateByBgno(int maxPgno);
    int getPageNumber();

    // --- 工厂方法 ---

    /**
     * 创建一个新的 PageCache
     */
    public static PageCache create(String path, long memory) {
        File f = new File(path + DB_SUFFIX);
        try {
            if (f.exists()) {
                Panic.panic(Error.FileExistsException);
            }
            if (!f.createNewFile()) {
                Panic.panic(Error.FileCannotRWException);
            }
        } catch (Exception e) {
            Panic.panic(e);
        }
        if (!f.canRead() || !f.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }

        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(f, "rw");
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }
        return new PageCacheImpl(raf, (int)(memory / PAGE_SIZE));
    }

    /**
     * 打开一个已有的 PageCache
     */
    public static PageCache open(String path, long memory) {
        File f = new File(path + DB_SUFFIX);
        if (!f.exists()) {
            Panic.panic(Error.FileNotExistsException);
        }
        if (!f.canRead() || !f.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }

        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(f, "rw");
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }
        return new PageCacheImpl(raf, (int)(memory / PAGE_SIZE));
    }
}